﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NSCEV.HBEDI.PowerLineDesign.Lib;

namespace NSCEV.HBEDI.PowerLineDesign.BLL
{
    /// <summary>
    /// 弧垂计算类
    /// </summary>
    public class HuChuiCalculate
    {
        //工况集合
        private EvConditions mConditions = null;

        public EvConditions Conditions
        {
            get { return mConditions; }
            set { mConditions = value; }
        }

        //导线型号
        private EvWireType evWireType = null;

        public EvWireType EvWireType
        {
            get { return evWireType; }
            set { evWireType = value; }
        }
        //地线型号
        private EvWireType evWireGroundType = null;

        public EvWireType EvWireGroundType
        {
            get { return evWireGroundType; }
            set { evWireGroundType = value; }
        }
        //安全系数
        private double mSafeK_Wire = 2.5;

        public double SafeK_Wire
        {
            get { return mSafeK_Wire; }
        }
        private double mSafeK_WireGround = 3.1;

        public double SafeK_WireGround
        {
            get { return mSafeK_WireGround; }
        }
        //C
        private int mC_Wire = 20;

        public int C_Wire
        {
            get { return mC_Wire; }
        }
        private int mC_WireGround = 25;

        public int C_WireGround
        {
            get { return mC_WireGround; }
        }

        private int dRepresent = 0;
        /// <summary>
        ///  代表档距
        /// </summary>
        public int DRepresent
        {
            get { return dRepresent; }
            set { dRepresent = value; }
        }
        public HuChuiCalculate()
        {
        }
        //调用完InitialData后，重置导地线型号、安全系数、代表档距参数
        public void ResetWireTypeData(EvWireType vWireType, EvWireType vWireGroundType, double vSafeK_Wire, double vSafeK_WireGround, int vRepresent)
        {
            evWireType = vWireType;
            evWireGroundType = vWireGroundType;
            mSafeK_Wire = vSafeK_Wire;
            mSafeK_WireGround = vSafeK_WireGround;
            dRepresent = vRepresent;
        }

        public ProjectCondition GetConditon(EnumConditionTypes condition)
        {
            for (int i = 0; i < mConditions.Count; i++)
            {
                if (mConditions.Get(i).ConditionTypes == condition)
                {
                    ProjectCondition huichui = mConditions.Get(i) as ProjectCondition;
                    return huichui;
                }

            }
            return null;
        }
        public Condition GetConditon(string condition)
        {
            return mConditions.Get(condition);

        }

        /// <summary>
        ///  获取某一个工况下的k值
        /// </summary>
        /// <param name="conditionName">工矿条件</param>
        /// <param name="isWire">true是导线，否则是地线</param>
        /// <returns>k值</returns>
        public double GetK(string conditionName, bool isWire)
        {

            Condition condition = mConditions.Get(conditionName);
            if (isWire)
            {
                ProjectCondition huichui = condition as ProjectCondition;
                if (huichui!=null)
                {
                    return huichui.k_Wire;
                }
                
            }
            else
            {
                ProjectCondition huichui = condition as ProjectCondition;
                if (huichui != null)
                {
                    return huichui.k_WireGround;
                }
            }
            return 0;
        }

        /// <summary>
        ///  获取某一个工况下的k值
        /// </summary>
        /// <param name="condition">工矿条件</param>
        /// <param name="isWire">true是导线，否则是地线</param>
        /// <returns>k值</returns>
        public double GetK(EnumConditionTypes condition, bool isWire)
        {
            for (int i = 0; i < mConditions.Count; i++)
            {
                if (mConditions.Get(i).ConditionTypes == condition)
                {
                    if (isWire)
                    {
                        ProjectCondition huichui = mConditions.Get(i) as ProjectCondition;
                        return huichui.k_Wire;
                    }
                    else
                    {
                        ProjectCondition huichui = mConditions.Get(i) as ProjectCondition;
                        return huichui.k_WireGround;
                    }
                }

            }
            return 0;
        }
        /// <summary>
        ///  获取某一个工况下的Fm值
        /// </summary>
        /// <param name="condition">工矿条件</param>
        /// <param name="isWire">true是导线，否则是地线</param>
        /// <returns>最大弧垂Fm值</returns>
        public double GetFm(EnumConditionTypes condition, bool isWire)
        {
            for (int i = 0; i < mConditions.Count; i++)
            {
                if (mConditions.Get(i).ConditionTypes == condition)
                {
                    if (isWire)
                    {
                        ProjectCondition huichui = mConditions.Get(i) as ProjectCondition;
                        return huichui.fm_Wire;
                    }
                    else
                    {
                        ProjectCondition huichui = mConditions.Get(i) as ProjectCondition;
                        return huichui.fm_WireGround;
                    }
                }

            }
            return 0;
        }
        /// <summary>
        /// 计算导线和地线的K值
        /// </summary>
        public void CalculateK()
        {
            if (mConditions != null && mConditions.Count > 0)
            {
                ProjectCondition huchui0 = mConditions.Get(0) as ProjectCondition;
                if (huchui0 == null)
                {
                    throw new ArithmeticException("不是有效的HuChuiCondition对象");
                }
                CalculateZL();
                for (int i = 0; i < mConditions.Count; i++)
                {
                    ProjectCondition huchui = mConditions.Get(i) as ProjectCondition;
                    huchui.k_Wire = HuChuiCalculate.K(huchui.ZHZH_Wire, evWireType.Area, huchui.ZL_Wire);
                    huchui.k_WireGround = HuChuiCalculate.K(huchui.ZHZH_WireGround, evWireGroundType.Area, huchui.ZL_WireGround);
                }
            }
        }
        /// <summary>
        /// 计算导线和地线的最大弧垂
        /// </summary>
        /// <param name="l">水平档距</param>
        /// <param name="beta">高差角</param>
        public void CalculateFm(double l, double beta)
        {
            if (mConditions != null && mConditions.Count > 0)
            {
                ProjectCondition huchui0 = mConditions.Get(0) as ProjectCondition;
                if (huchui0 == null)
                {
                    throw new ArithmeticException("不是有效的HuChuiCondition对象");
                }
                CalculateK();
                for (int i = 0; i < mConditions.Count; i++)
                {
                    ProjectCondition huchui = mConditions.Get(i) as ProjectCondition;
                    huchui.k_Wire = HuChuiCalculate.CaculateFm(l, beta, huchui.k_Wire);
                    huchui.k_WireGround = HuChuiCalculate.CaculateFm(l, beta, huchui.k_WireGround);
                }
            }
        }
        /// <summary>
        /// 计算张力
        /// </summary>
        public void CalculateZL()
        {
            if (mConditions != null && mConditions.Count > 0)
            {
                double[,] LJDJParamsWire = new double[4, 3];
                double[,] LJDJParamsWireGround = new double[4, 3];
                for (int i = 0; i < mConditions.Count; i++)
                {
                    Condition condi = mConditions.Get(i);
                    //导线
                    condi.ZHZH_Wire = TowerCaculate.GetP(condi.WindWire, condi.Ice, evWireType.W, evWireType.D);
                    condi.VZH_Wire = TowerCaculate.GetP(0, condi.Ice, evWireType.W, evWireType.D);
                    condi.WindZH_Wire = TowerCaculate.GetP5(condi.WindWire, condi.Ice, evWireType.W, evWireType.D);
                    //地线
                    condi.ZHZH_WireGround = TowerCaculate.GetP(condi.WindWireGround, condi.Ice, evWireGroundType.W, evWireGroundType.D);
                    condi.VZH_WireGround = TowerCaculate.GetP(0, condi.Ice, evWireGroundType.W, evWireGroundType.D);
                    condi.WindZH_WireGround = TowerCaculate.GetP5(condi.WindWireGround, condi.Ice, evWireGroundType.W, evWireGroundType.D);

                    if (condi.ConditionName == "最低气温" || condi.ConditionName == "最低温" || condi.ConditionName == "低温")
                    {
                        LJDJParamsWire[0, 0] = condi.Tempreture;
                        LJDJParamsWire[0, 1] = condi.ZHZH_Wire;
                        LJDJParamsWire[0, 2] = evWireType.Tp / (double)mSafeK_Wire;

                        LJDJParamsWireGround[0, 0] = condi.Tempreture;
                        LJDJParamsWireGround[0, 1] = condi.ZHZH_WireGround;
                        LJDJParamsWireGround[0, 2] = evWireGroundType.Tp / (double)mSafeK_WireGround;
                    }
                    if (condi.ConditionName == "平均气温" || condi.ConditionName == "年平")
                    {
                        LJDJParamsWire[1, 0] = condi.Tempreture;
                        LJDJParamsWire[1, 1] = condi.ZHZH_Wire;
                        LJDJParamsWire[1, 2] = evWireType.Tp * mC_Wire / 100;

                        LJDJParamsWireGround[1, 0] = condi.Tempreture;
                        LJDJParamsWireGround[1, 1] = condi.ZHZH_WireGround;
                        LJDJParamsWireGround[1, 2] = evWireGroundType.Tp * mC_WireGround / 100;
                    }
                    if (condi.ConditionName == "被冰" || condi.ConditionName == "覆冰")
                    {
                        LJDJParamsWire[3, 0] = condi.Tempreture;
                        LJDJParamsWire[3, 1] = condi.ZHZH_Wire;
                        LJDJParamsWire[3, 2] = evWireType.Tp / (double)mSafeK_Wire;

                        LJDJParamsWireGround[3, 0] = condi.Tempreture;
                        LJDJParamsWireGround[3, 1] = condi.ZHZH_WireGround;
                        LJDJParamsWireGround[3, 2] = evWireGroundType.Tp / (double)mSafeK_WireGround;
                    }

                    //风载荷
                    if (condi.ConditionName == "最大风" || condi.ConditionName == "大风")
                    {
                        LJDJParamsWire[2, 0] = condi.Tempreture;
                        LJDJParamsWire[2, 1] = condi.ZHZH_Wire;
                        LJDJParamsWire[2, 2] = evWireType.Tp / (double)mSafeK_Wire;

                        LJDJParamsWireGround[2, 0] = condi.Tempreture;
                        LJDJParamsWireGround[2, 1] = condi.ZHZH_WireGround;
                        LJDJParamsWireGround[2, 2] = evWireGroundType.Tp / (double)mSafeK_WireGround;
                    }
                }
                double EA = evWireType.Area * evWireType.E;
                double EA1 = EA * evWireType.Alpha / Math.Pow(10, 6);
                double[,] LJDJRes = TowerCaculate.LJDJ(EA, EA1, LJDJParamsWire);

                double[,] LJDJWithEAWire = new double[5, 2];
                LJDJWithEAWire[0, 0] = EA;
                LJDJWithEAWire[0, 1] = EA1;

                double EAWireGround = evWireGroundType.Area * evWireGroundType.E;
                double EA1WireGround = EAWireGround * evWireGroundType.Alpha / Math.Pow(10, 6);
                double[,] LJDJResGround = TowerCaculate.LJDJ(EAWireGround, EA1WireGround, LJDJParamsWireGround);

                double[,] LJDJWithEAWireGround = new double[5, 2];
                LJDJWithEAWireGround[0, 0] = EAWireGround;
                LJDJWithEAWireGround[0, 1] = EA1WireGround;
                for (int i = 1; i < 5; i++)
                {
                    LJDJWithEAWire[i, 0] = LJDJRes[i - 1, 0];
                    LJDJWithEAWire[i, 1] = LJDJRes[i - 1, 1];

                    LJDJWithEAWireGround[i, 0] = LJDJResGround[i - 1, 0];
                    LJDJWithEAWireGround[i, 1] = LJDJResGround[i - 1, 1];
                }

                for (int i = 0; i < mConditions.Count; i++)
                {
                    Condition condi = mConditions.Get(i);
                    condi.ZL_Wire = TowerCaculate.GetT(dRepresent, condi.Tempreture, condi.ZHZH_Wire, LJDJWithEAWire, LJDJParamsWire);
                    condi.ZL_WireGround = TowerCaculate.GetT(dRepresent, condi.Tempreture, condi.ZHZH_WireGround, LJDJWithEAWireGround, LJDJParamsWireGround);

                }
            }
        }

        /// <summary>
        ///  计算最大弧垂
        /// </summary>
        /// <param name="l">档距，两悬挂点之水平距离</param>
        /// <param name="belta">高差角</param>
        /// <param name="k">导线K值</param>
        /// <returns></returns>
        public static double CaculateFm(double l, double belta, double k)
        {
            double fm = l * l * k / 4;
            return fm;
        }

        /// <summary>
        /// 计算K值，k=电线综合比载/(8*水平应力)
        /// </summary>
        /// <param name="ZHZH">综合载荷</param>
        /// <param name="A">截面积</param>
        /// <param name="zL">水平张力</param>
        /// <returns></returns>
        public static double K(double ZHZH, double A, double zL)
        {
            double K0 = ZHZH / zL / 8;
            return K0;
        }
    }

}
